/*
 * @Author: asushiye
 * @Date: 2020-07-03 08:51:09
 * @Commit: 身份认证， 获取用户和应用信息
 * userAccount： 格式；{"user_name":"admin","organization":"daphne-admin","exp":1651465999,"jti":"e990db3f-1804-460e-8c5c-0cedcb6f4e9d","client_id":"wmsClient"}
 */
import { HttpContext, HttpHeaders } from '@angular/common/http';
import { Injectable, Inject, Injector } from '@angular/core';
import { ALLOW_ANONYMOUS, DA_SERVICE_TOKEN, ITokenModel, ITokenService, JWTTokenModel } from '@delon/auth';
import { _HttpClient } from '@delon/theme';
import { Observable } from 'rxjs';

import { AfCookieService } from './af-cookie.service';
import { gw_ms_user, gw_ms_auth } from './af-microservice';

@Injectable({
  providedIn: 'root'
})
export class AfSecurityService {
  public userAccount: any = { username: '', userId: null };
  private clientInfo: any = { grantType: 'password', clientId: 'wmsClient', clientSecret: 'secret' };

  constructor(
    private http: _HttpClient,
    @Inject(DA_SERVICE_TOKEN) private tokenService: ITokenService,
    private cookieSrv: AfCookieService
  ) {}

  get userName() {
    let username: any = this.userAccount.username;
    if (!username || username.length <= 0) {
      const jwtToken = this.tokenService.get<JWTTokenModel>(JWTTokenModel);
      const jwt = jwtToken!.payload;
      if (jwt) {
        if (jwt['user_name']) {
          username = jwt['user_name'];
          if (username.length >= 1) {
            this.userAccount.username = username;
          }
        }
      }
    }
    return username;
  }

  get token() {
    const jwtToken = this.tokenService.get<JWTTokenModel>(JWTTokenModel);
    return jwtToken.token;
  }

  // 获取用户名称3个字符，用于图标显示，提示名字一般都是三个字符
  get avatarName() {
    const avatar = this.userName as String;
    if (avatar && avatar.length >= 1) {
      return avatar.substring(0, 3);
    }
    return 'U';
  }

  // 启动- 获取应用程序,用户信息,菜单信息,权限信息
  public getAuthData(menus: boolean = true, role: boolean = false, authority: boolean = false): Observable<any> {
    console.log('Start requesting remote app, user, menu, permission and other data');

    const url = `${gw_ms_user}/auth/app?menus=${menus}&role=${role}&authority=${authority}`;
    return this.http.get(url, null);
  }

  // 未知
  public getAuthDataForHeader(
    menus: boolean = true,
    role: boolean = false,
    authority: boolean = false,
    token?: any | null
  ): Observable<any> {
    const url = `${gw_ms_user}/auth/app?menus=${menus}&role=${role}&authority=${authority}`;
    const option = {
      headers: new HttpHeaders({ authorization: token }),
      context: new HttpContext().set(ALLOW_ANONYMOUS, true)
    };
    return this.http.get(url, '', option);
  }

  // 获取手机验证码
  public getCaptcha(phone: string): Observable<any> {
    const url = `${gw_ms_auth}/phone/verification/code/generate?phone=${phone}`;
    return this.http.get(url, null, {
      context: new HttpContext().set(ALLOW_ANONYMOUS, true)
    });
  }

  public login(username: string, password: string, mobile: string, captcha: string, type?: any): Observable<any> {
    let url = `${gw_ms_auth}/phone_login`;
    let params: any;
    if (type === 0) {
      url = `${gw_ms_auth}/perform_login`;
      params = {
        username: username,
        password: password
      };
    } else {
      params = {
        phone: mobile,
        verificationCode: captcha
      };
    }
    return this.http.form(url, null, params, {
      context: new HttpContext().set(ALLOW_ANONYMOUS, true)
    });
  }

  // 基于Oauth2实现认证
  /* API返回结构
  {
    "access_token":"eyJh.In0.1JIX",
    "token_type":"bearer",
    "refresh_token":"eyJh.0In.UCAs",
    "expires_in":2284,
    "scope":"auth.read person.read person.write",
    "organization":"daphne-admin",
    "jti":"e22536b6-44ab-4351-bcbc-d6e4070179bb"
  }*/
  public loginByOauth2(username: string, password: string, mobile: string, captcha: string, type?: any): Observable<any> {
    let url = `${gw_ms_auth}/phone_login`;
    let params: any;
    if (type === 0) {
      url = `${gw_ms_auth}/oauth/token`;
      params = {
        username: username,
        password: password,
        grant_type: this.clientInfo.grantType,
        client_id: this.clientInfo.clientId,
        client_secret: this.clientInfo.clientSecret
      };
    } else {
      params = {
        phone: mobile,
        verificationCode: captcha,
        grant_type: this.clientInfo.grantType,
        client_id: this.clientInfo.clientId,
        client_secret: this.clientInfo.clientSecret
      };
    }
    return this.http.form(url, null, params, {
      context: new HttpContext().set(ALLOW_ANONYMOUS, true)
    });
  }
}
